<?php

namespace fast;

use app\common\exception\NormalException;
use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\LabelAlignment;
use Endroid\QrCode\QrCode;
use Zxing\QrReader;

/**
 * 二维码处理类
 */
class FastQrcode
{
    /**
     * 生成二维码
     *
     * @param string $code_text 要编码的文本
     * @param string $save_path 保存路径
     * @param string|null $center_logo 居中图标路径（可选）
     * @return bool
     * @throws NormalException
     */
    public static function build(string $code_text, string $save_path, ?string $center_logo = null): bool
    {
        try {
            $qrCode = new QrCode($code_text);
            $qrCode->setSize(300);
            $qrCode->setMargin(10);

            // 设置高级选项
            $qrCode->setWriterByName('png');
            $qrCode->setEncoding('UTF-8');
            $qrCode->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH());
            $qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]);
            $qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]);

            // 设置居中图标
            if ($center_logo) {
                $qrCode->setLogoPath($center_logo);
                $qrCode->setLogoSize(60, 60);
            }

            $qrCode->setValidateResult(false);

            $qrCode->writeFile($save_path);

            if (!is_file($save_path)) {
                throw new NormalException('生成二维码失败');
            }

            return true;
        } catch (\Exception $e) {
            throw new NormalException('生成二维码时发生错误: ' . $e->getMessage());
        }
    }

    /**
     * 解析二维码
     *
     * @param string $imagePath 图片路径
     * @return string
     * @throws NormalException
     */
    public static function identify(string $imagePath): string
    {
        try {
            $result = (new QrReader($imagePath))->text();

            if (!$result) {
                throw new NormalException('获取二维码失败,请重新上传');
            }

            return $result;
        } catch (\Exception $e) {
            throw new NormalException('解析二维码时发生错误: ' . $e->getMessage());
        }
    }

    /**
     * 显示二维码
     *
     * @param string $code_text 要编码的文本
     * @param string|null $center_logo 居中图标路径（可选）
     * @throws NormalException
     */
    public static function display(string $code_text, ?string $center_logo = null)
    {
        try {
            $qrCode = new QrCode($code_text);
            $qrCode->setSize(300);
            $qrCode->setMargin(10);

            // 设置高级选项
            $qrCode->setWriterByName('png');
            $qrCode->setEncoding('UTF-8');
            $qrCode->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH());
            $qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]);
            $qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]);

            // 设置居中图标
            if ($center_logo) {
                $qrCode->setLogoPath($center_logo);
                $qrCode->setLogoSize(60, 60);
            }

            $qrCode->setValidateResult(false);

            header('Content-Type: '.$qrCode->getContentType());
            echo $qrCode->writeString();
            exit();
        } catch (\Exception $e) {
            throw new NormalException('显示二维码时发生错误: ' . $e->getMessage());
        }
    }

    /**
     * 验证二维码内容
     *
     * @param string $code_text 要验证的文本
     * @param callable $validator 验证回调函数
     * @return bool
     * @throws NormalException
     */
    public static function validate(string $code_text, callable $validator): bool
    {
        try {
            return $validator($code_text);
        } catch (\Exception $e) {
            throw new NormalException('验证二维码内容时发生错误: ' . $e->getMessage());
        }
    }

    /**
     * 批量生成二维码
     *
     * @param array $code_texts 要编码的文本数组
     * @param string $save_dir 保存目录
     * @param string|null $center_logo 居中图标路径（可选）
     * @return array
     * @throws NormalException
     */
    public static function bulkBuild(array $code_texts, string $save_dir, ?string $center_logo = null): array
    {
        $results = [];
        foreach ($code_texts as $code_text) {
            $save_path = $save_dir . DIRECTORY_SEPARATOR . md5($code_text) . '.png';
            $results[$code_text] = self::build($code_text, $save_path, $center_logo);
        }
        return $results;
    }

    /**
     * 批量解析二维码
     *
     * @param array $imagePaths 图片路径数组
     * @return array
     * @throws NormalException
     */
    public static function bulkIdentify(array $imagePaths): array
    {
        $results = [];
        foreach ($imagePaths as $imagePath) {
            $results[$imagePath] = self::identify($imagePath);
        }
        return $results;
    }


}
